package com.agileplex.codeminer.index;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;

import com.agileplex.codeminer.commons.props.PropsUtil;
import com.agileplex.codeminer.scm.IDirectory;
import com.agileplex.codeminer.scm.IFile;
import com.agileplex.codeminer.scm.IRepository;
import com.agileplex.codeminer.scm.IVersion;
import com.agileplex.codeminer.scm.IVersionFS;

/**
 * Build a index for repository
 * 
 * @creator Weiming Yin
 * @date 2007-7-17
 *
 * @lastmodified
 * @author $Author: yinweiming $
 * @version $Revision: 15 $, $Date: 2007-07-16 18:12:59 +0000 (Mon, 16 Jul 2007) $
 */
public class IndexBuilder {
	static Logger logger = Logger.getLogger(IndexBuilder.class);
	
	static String rootDir = ".";
	static {
		rootDir = PropsUtil.getString("codeminer.conf", "RootDir");
		if (rootDir == null) {
			rootDir = File.separatorChar + "indexes";
		}
	}
	
	public static void buildIndex(IRepository repos, IVersion v) throws IOException {
		final String uniqId = repos.getUniqId();
		final String version = v.getVersion() == null ? "" : v.getVersion().toString();
		
		IVersionFS fsTree = repos.getFSTree();

		final IDirectory root = fsTree.getRootDir(v);
		new Thread(new Runnable() {
				public void run() {
					try {
						IndexWriter writer = new IndexWriter(new File(rootDir, uniqId), new StandardAnalyzer(), true);
						doBuild(writer, root);
						writer.optimize();
						writer.close();
					} catch (IOException e) {
						logger.error(e);
					}
				}
				
				private void doBuild(IndexWriter writer, IDirectory parent) {
					for (Iterator<? extends IFile> it = parent.listFiles().iterator(); it.hasNext();) {
						IFile f = it.next();
						Document doc = new Document();
						doc.add(new Field("type", "FILE", Field.Store.NO, Field.Index.NO));
						doc.add(new Field("version", version, Field.Store.YES, Field.Index.UN_TOKENIZED));
						doc.add(new Field("name", f.getName(), Field.Store.YES, Field.Index.UN_TOKENIZED));
						doc.add(new Field("mimeType", f.getMimeType(), Field.Store.YES, Field.Index.UN_TOKENIZED));
						doc.add(new Field("content", f.getContent(), Field.Store.YES, Field.Index.TOKENIZED));
						try {
							writer.addDocument(doc);
						} catch (IOException e) {
							logger.error(e);
							//TODO: weiming -- Should add a system error log , and recover it later. 
						}
					}
					
					for (Iterator<? extends IDirectory> it = parent.listDirs().iterator(); it.hasNext();) {
						IDirectory dir = it.next();
						Document doc = new Document();
						doc.add(new Field("type", "DIRECTORY", Field.Store.NO, Field.Index.NO));
						doc.add(new Field("version", version, Field.Store.YES, Field.Index.UN_TOKENIZED));
						doc.add(new Field("name", dir.getName(), Field.Store.YES, Field.Index.UN_TOKENIZED));
						try {
							writer.addDocument(doc);
						} catch (IOException e) {
							logger.error(e);
							//TODO: weiming -- Should add a system error log , and recover it later. 
						}
						
						doBuild(writer, dir);
					}
				}
			}).start();
		
		
	}
}
